package com.mingserve.common.core.utils;

import java.math.BigInteger;
import java.nio.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.DoubleAdder;
import java.util.concurrent.atomic.LongAdder;

/**
 * 对数字和字节进行转换。
 * 假设数据存储是以小端模式存储的：
 * <ul>
 *     <li>byte: 字节类型 占8位二进制 00000000</li>
 *     <li>char: 字符类型 占2个字节 16位二进制 byte[0] byte[1]</li>
 *     <li>int : 整数类型 占4个字节 32位二进制 byte[0] byte[1] byte[2] byte[3]</li>
 *     <li>long: 长整数类型 占8个字节 64位二进制 byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7]</li>
 *     <li>float: 浮点数(小数) 占4个字节 32位二进制 byte[0] byte[1] byte[2] byte[3]</li>
 *     <li>double: 双精度浮点数(小数) 占8个字节 64位二进制 byte[0] byte[1] byte[2] byte[3] byte[4]byte[5] byte[6] byte[7]</li>
 * </ul>
 * byte[] 与 double[],float[],int[],long[],short[] 互转
 * byte[] 与 double,float,long,int,char,string 互转
 *
 * @author lvwshuai
 * @date 2022-10-21
 */
public class ByteUtils
{
    /**
     * 大小端模式
     * 小端（little-endian）：低位字节在前，高位字节在后
     * 大端（Big-Endian）：高位字节在前，低位字节在后
     */
    public static final ByteOrder DEFAULT_ORDER = ByteOrder.LITTLE_ENDIAN;
    /**
     * CPU的字节序
     */
    public static final ByteOrder CPU_ENDIAN = "little".equals(System.getProperty("sun.cpu.endian")) ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN;

    /**
     * byte[] TO double[]
     * 默认以小端序转换
     *
     * @param input byte数组
     * @return
     */
    public static double[] toDoubleArray(byte[] input)
    {
        return toDoubleArray(input, DEFAULT_ORDER);
    }

    /**
     * byte[] TO double[]
     * 自定义端序
     *
     * @param input     byte数组
     * @param byteOrder 端序
     * @return
     */
    public static double[] toDoubleArray(byte[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer byteBuffer = ByteBuffer.wrap(input);
        byteBuffer.order(byteOrder);
        DoubleBuffer buffer = byteBuffer.asDoubleBuffer();
        double[] res = new double[buffer.remaining()];
        buffer.get(res);
        return res;
    }

    /**
     * byte[] TO float[]
     * 默认以小端序转换
     *
     * @param input byte数组
     * @return
     */
    public static float[] toFloatArray(byte[] input)
    {
        return toFloatArray(input, DEFAULT_ORDER);
    }

    /**
     * byte[] TO float[]
     * 自定义端序
     *
     * @param input     byte数组
     * @param byteOrder 端序
     * @return
     */
    public static float[] toFloatArray(byte[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer byteBuffer = ByteBuffer.wrap(input);
        byteBuffer.order(byteOrder);
        FloatBuffer buffer = byteBuffer.asFloatBuffer();
        float[] res = new float[buffer.remaining()];
        buffer.get(res);
        return res;
    }

    /**
     * byte[] TO int[]
     * 默认以小端序转换
     *
     * @param input byte数组
     * @return
     */
    public static int[] toIntArray(byte[] input)
    {
        return toIntArray(input, DEFAULT_ORDER);
    }

    /**
     * byte[] TO int[]
     * 自定义端序
     *
     * @param input     byte数组
     * @param byteOrder 端序
     * @return
     */
    public static int[] toIntArray(byte[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer byteBuffer = ByteBuffer.wrap(input);
        byteBuffer.order(byteOrder);
        IntBuffer buffer = byteBuffer.asIntBuffer();
        int[] res = new int[buffer.remaining()];
        buffer.get(res);
        return res;
    }

    /**
     * byte[] TO long[]
     * 默认以小端序转换
     *
     * @param input byte数组
     * @return
     */
    public static long[] toLongArray(byte[] input)
    {
        return toLongArray(input, DEFAULT_ORDER);
    }

    /**
     * byte[] TO long[]
     * 自定义端序
     *
     * @param input     byte数组
     * @param byteOrder 端序
     * @return
     */
    public static long[] toLongArray(byte[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer byteBuffer = ByteBuffer.wrap(input);
        byteBuffer.order(byteOrder);
        LongBuffer buffer = byteBuffer.asLongBuffer();
        long[] res = new long[buffer.remaining()];
        buffer.get(res);
        return res;
    }

    /**
     * byte[] TO short[]
     * 默认以小端序转换
     *
     * @param input byte数组
     * @return
     */
    public static short[] toShortArray(byte[] input)
    {
        return toShortArray(input, DEFAULT_ORDER);
    }

    /**
     * byte[] TO short[]
     * 自定义端序
     *
     * @param input byte数组
     * @return
     */
    public static short[] toShortArray(byte[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer byteBuffer = ByteBuffer.wrap(input);
        byteBuffer.order(byteOrder);
        ShortBuffer buffer = byteBuffer.asShortBuffer();
        short[] res = new short[buffer.remaining()];
        buffer.get(res);
        return res;
    }

    /**
     * double[] TO byte[]
     * 默认以小端序转换
     *
     * @param input double数组
     * @return
     */
    public static byte[] toByteArray(double[] input)
    {
        return toByteArray(input, DEFAULT_ORDER);
    }

    /**
     * double[] TO byte[]
     * 自定义端序
     *
     * @param input     double数组
     * @param byteOrder 端序
     * @return
     */
    public static byte[] toByteArray(double[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        return toByteBuffer(DoubleBuffer.wrap(input), byteOrder).array();
    }

    /**
     * {@link DoubleBuffer} TO {@link ByteBuffer}
     *
     * @param input
     * @param byteOrder 端序
     * @return
     */
    public static ByteBuffer toByteBuffer(DoubleBuffer input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer buffer = ByteBuffer.allocate(input.capacity() * (Double.SIZE / 8));
        buffer.order(byteOrder);
        while (input.hasRemaining()) {
            buffer.putDouble(input.get());
        }
        return buffer;
    }

    /**
     * float[] TO byte[]
     *
     * @param input float数组
     * @return
     */
    public static byte[] toByteArray(float[] input)
    {
        return toByteArray(input, DEFAULT_ORDER);
    }

    /**
     * float[] TO byte[]
     *
     * @param input     float数组
     * @param byteOrder 端序
     * @return
     */
    public static byte[] toByteArray(float[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        return toByteBuffer(FloatBuffer.wrap(input), byteOrder).array();
    }

    /**
     * {@link FloatBuffer} TO {@link ByteBuffer}
     *
     * @param input
     * @param byteOrder 端序
     * @return
     */
    public static ByteBuffer toByteBuffer(FloatBuffer input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer buffer = ByteBuffer.allocate(input.capacity() * (Float.SIZE / 8));
        buffer.order(byteOrder);
        while (input.hasRemaining()) {
            buffer.putFloat(input.get());
        }
        return buffer;
    }

    /**
     * int[] TO byte[]
     * 默认以小端序转换
     *
     * @param input int数组
     * @return
     */
    public static byte[] toByteArray(int[] input)
    {
        return toByteArray(input, DEFAULT_ORDER);
    }

    /**
     * int[] TO byte[]
     * 自定义端序
     *
     * @param input     int数组
     * @param byteOrder 端序
     * @return
     */
    public static byte[] toByteArray(int[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        return toByteBuffer(IntBuffer.wrap(input), byteOrder).array();
    }

    /**
     * {@link IntBuffer} TO {@link ByteBuffer}
     *
     * @param input
     * @param byteOrder 端序
     * @return
     */
    public static ByteBuffer toByteBuffer(IntBuffer input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer buffer = ByteBuffer.allocate(input.capacity() * (Integer.SIZE / 8));
        buffer.order(byteOrder);
        while (input.hasRemaining()) {
            buffer.putInt(input.get());
        }
        return buffer;
    }

    /**
     * long[] TO byte[]
     * 默认以小端序转换
     *
     * @param input long数组
     * @return
     */
    public static byte[] toByteArray(long[] input)
    {
        return toByteArray(input, DEFAULT_ORDER);
    }

    /**
     * long[] TO byte[]
     * 自定义端序
     *
     * @param input     long数组
     * @param byteOrder 端序
     * @return
     */
    public static byte[] toByteArray(long[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        return toByteBuffer(LongBuffer.wrap(input), byteOrder).array();
    }

    /**
     * {@link LongBuffer} TO {@link ByteBuffer}
     *
     * @param input
     * @param byteOrder 端序
     * @return
     */
    public static ByteBuffer toByteBuffer(LongBuffer input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer buffer = ByteBuffer.allocate(input.capacity() * (Long.SIZE / 8));
        buffer.order(byteOrder);
        while (input.hasRemaining()) {
            buffer.putLong(input.get());
        }
        return buffer;
    }

    /**
     * short[] TO byte[]
     * 默认以小端序转换
     *
     * @param input short数组
     * @return
     */
    public static byte[] toByteArray(short[] input)
    {
        return toByteArray(input, DEFAULT_ORDER);
    }

    /**
     * short[] TO byte[]
     * 自定义端序
     *
     * @param input     short数组
     * @param byteOrder 端序
     * @return
     */
    public static byte[] toByteArray(short[] input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        return toByteBuffer(ShortBuffer.wrap(input), byteOrder).array();
    }

    /**
     * {@link ShortBuffer} TO {@link ByteBuffer}
     *
     * @param input
     * @param byteOrder 端序
     * @return
     */
    public static ByteBuffer toByteBuffer(ShortBuffer input, final ByteOrder byteOrder)
    {
        if (input == null) return null;
        ByteBuffer buffer = ByteBuffer.allocate(input.capacity() * (Short.SIZE / 8));
        buffer.order(byteOrder);
        while (input.hasRemaining()) {
            buffer.putShort(input.get());
        }
        return buffer;
    }

    /**
     * int转byte
     *
     * @param intValue int值
     * @return byte值
     */
    public static byte intToByte(int intValue)
    {
        return (byte) intValue;
    }

    /**
     * byte转无符号int
     *
     * @param byteValue byte值
     * @return 无符号int值
     */
    public static int byteToUnsignedInt(byte byteValue)
    {
        // Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
        return byteValue & 0xFF;
    }

    /**
     * byte[]转short
     * 默认以小端序转换
     *
     * @param bytes byte数组
     * @return short值
     */
    public static short bytesToShort(byte[] bytes)
    {
        return bytesToShort(bytes, DEFAULT_ORDER);
    }

    /**
     * byte[]转short
     * 自定义端序
     *
     * @param bytes     byte数组，长度必须为2
     * @param byteOrder 端序
     * @return short值
     */
    public static short bytesToShort(final byte[] bytes, final ByteOrder byteOrder)
    {
        return bytesToShort(bytes, 0, byteOrder);
    }

    /**
     * byte[]转short
     * 自定义端序
     *
     * @param bytes     byte数组，长度必须大于2
     * @param start     开始位置
     * @param byteOrder 端序
     * @return short值
     */
    public static short bytesToShort(final byte[] bytes, final int start, final ByteOrder byteOrder)
    {
        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            //小端模式，数据的高字节保存在内存的高地址中，而数据的低字节保存在内存的低地址中
            return (short) (bytes[start] & 0xff | (bytes[start + 1] & 0xff) << Byte.SIZE);
        } else {
            return (short) (bytes[start + 1] & 0xff | (bytes[start] & 0xff) << Byte.SIZE);
        }
    }

    /**
     * short转byte[]
     * 默认以小端序转换
     *
     * @param shortValue short值
     * @return byte数组
     */
    public static byte[] shortToBytes(short shortValue)
    {
        return shortToBytes(shortValue, DEFAULT_ORDER);
    }

    /**
     * short转byte[]
     * 自定义端序
     *
     * @param shortValue short值
     * @param byteOrder  端序
     * @return byte数组
     */
    public static byte[] shortToBytes(short shortValue, ByteOrder byteOrder)
    {
        byte[] b = new byte[Short.BYTES];
        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            b[0] = (byte) (shortValue & 0xff);
            b[1] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
        } else {
            b[1] = (byte) (shortValue & 0xff);
            b[0] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
        }
        return b;
    }

    /**
     * byte[]转int值
     * 默认以小端序转换
     *
     * @param bytes byte数组
     * @return int值
     */
    public static int bytesToInt(byte[] bytes)
    {
        return bytesToInt(bytes, DEFAULT_ORDER);
    }

    /**
     * byte[]转int值
     * 自定义端序
     *
     * @param bytes     byte数组
     * @param byteOrder 端序
     * @return int值
     */
    public static int bytesToInt(byte[] bytes, ByteOrder byteOrder)
    {
        return bytesToInt(bytes, 0, byteOrder);
    }

    /**
     * byte[]转int
     * 自定义端序
     *
     * @param bytes     byte数组
     * @param start     开始位置（包含）
     * @param byteOrder 端序
     * @return int值
     */
    public static int bytesToInt(byte[] bytes, int start, ByteOrder byteOrder)
    {
        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            return bytes[start] & 0xFF | //
                    (bytes[1 + start] & 0xFF) << 8 | //
                    (bytes[2 + start] & 0xFF) << 16 | //
                    (bytes[3 + start] & 0xFF) << 24; //
        } else {
            return bytes[3 + start] & 0xFF | //
                    (bytes[2 + start] & 0xFF) << 8 | //
                    (bytes[1 + start] & 0xFF) << 16 | //
                    (bytes[start] & 0xFF) << 24; //
        }
    }

    /**
     * int转byte[]
     * 默认以小端序转换
     *
     * @param intValue int值
     * @return byte数组
     */
    public static byte[] intToBytes(int intValue)
    {
        return intToBytes(intValue, DEFAULT_ORDER);
    }

    /**
     * int转byte[]
     * 自定义端序
     *
     * @param intValue  int值
     * @param byteOrder 端序
     * @return byte数组
     */
    public static byte[] intToBytes(int intValue, ByteOrder byteOrder)
    {

        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            return new byte[]{ //
                    (byte) (intValue & 0xFF), //
                    (byte) ((intValue >> 8) & 0xFF), //
                    (byte) ((intValue >> 16) & 0xFF), //
                    (byte) ((intValue >> 24) & 0xFF) //
            };
        } else {
            return new byte[]{ //
                    (byte) ((intValue >> 24) & 0xFF), //
                    (byte) ((intValue >> 16) & 0xFF), //
                    (byte) ((intValue >> 8) & 0xFF), //
                    (byte) (intValue & 0xFF) //
            };
        }

    }

    /**
     * long转byte[]
     * 默认以小端序转换
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param longValue long值
     * @return byte数组
     */
    public static byte[] longToBytes(long longValue)
    {
        return longToBytes(longValue, DEFAULT_ORDER);
    }

    /**
     * long转byte[]
     * 自定义端序
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param longValue long值
     * @param byteOrder 端序
     * @return byte数组
     */
    public static byte[] longToBytes(long longValue, ByteOrder byteOrder)
    {
        byte[] result = new byte[Long.BYTES];
        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            for (int i = 0; i < result.length; i++) {
                result[i] = (byte) (longValue & 0xFF);
                longValue >>= Byte.SIZE;
            }
        } else {
            for (int i = (result.length - 1); i >= 0; i--) {
                result[i] = (byte) (longValue & 0xFF);
                longValue >>= Byte.SIZE;
            }
        }
        return result;
    }

    /**
     * byte[]转long
     * 默认以小端序转换
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param bytes byte数组
     * @return long值
     */
    public static long bytesToLong(byte[] bytes)
    {
        return bytesToLong(bytes, DEFAULT_ORDER);
    }

    /**
     * byte[]转long
     * 自定义端序
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param bytes     byte数组
     * @param byteOrder 端序
     * @return long值
     */
    public static long bytesToLong(byte[] bytes, ByteOrder byteOrder)
    {
        return bytesToLong(bytes, 0, byteOrder);
    }

    /**
     * byte[]转long
     * 自定义端序
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param bytes     byte数组
     * @param start     计算数组开始位置
     * @param byteOrder 端序
     * @return long值
     */
    public static long bytesToLong(byte[] bytes, int start, ByteOrder byteOrder)
    {
        long values = 0;
        if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
            for (int i = (Long.BYTES - 1); i >= 0; i--) {
                values <<= Byte.SIZE;
                values |= (bytes[i + start] & 0xff);
            }
        } else {
            for (int i = 0; i < Long.BYTES; i++) {
                values <<= Byte.SIZE;
                values |= (bytes[i + start] & 0xff);
            }
        }
        return values;
    }

    /**
     * float转byte[]，默认以小端序转换
     *
     * @param floatValue float值
     * @return byte数组
     */
    public static byte[] floatToBytes(float floatValue)
    {
        return floatToBytes(floatValue, DEFAULT_ORDER);
    }

    /**
     * float转byte[]，自定义端序
     *
     * @param floatValue float值
     * @param byteOrder  端序
     * @return byte数组
     */
    public static byte[] floatToBytes(float floatValue, ByteOrder byteOrder)
    {
        return intToBytes(Float.floatToIntBits(floatValue), byteOrder);
    }

    /**
     * byte[]转float
     * 默认以小端序转换
     *
     * @param bytes byte数组
     * @return float值
     */
    public static float bytesToFloat(byte[] bytes)
    {
        return bytesToFloat(bytes, DEFAULT_ORDER);
    }

    /**
     * byte[]转float
     * 自定义端序
     *
     * @param bytes     byte数组
     * @param byteOrder 端序
     * @return float值
     */
    public static float bytesToFloat(byte[] bytes, ByteOrder byteOrder)
    {
        return Float.intBitsToFloat(bytesToInt(bytes, byteOrder));
    }

    /**
     * double转byte[]
     * 默认以小端序转换
     *
     * @param doubleValue double值
     * @return byte数组
     */
    public static byte[] doubleToBytes(double doubleValue)
    {
        return doubleToBytes(doubleValue, DEFAULT_ORDER);
    }

    /**
     * double转byte[]
     * 自定义端序
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param doubleValue double值
     * @param byteOrder   端序
     * @return byte数组
     */
    public static byte[] doubleToBytes(double doubleValue, ByteOrder byteOrder)
    {
        return longToBytes(Double.doubleToLongBits(doubleValue), byteOrder);
    }

    /**
     * byte[]转Double
     * 默认以小端序转换
     *
     * @param bytes byte数组
     * @return long值
     */
    public static double bytesToDouble(byte[] bytes)
    {
        return bytesToDouble(bytes, DEFAULT_ORDER);
    }

    /**
     * byte[]转double
     * 自定义端序
     *
     * @param bytes     byte数组
     * @param byteOrder 端序
     * @return long值
     */
    public static double bytesToDouble(byte[] bytes, ByteOrder byteOrder)
    {
        return Double.longBitsToDouble(bytesToLong(bytes, byteOrder));
    }

    /**
     * 将{@link Number}转换为
     *
     * @param number 数字
     * @return bytes
     */
    public static byte[] numberToBytes(Number number)
    {
        return numberToBytes(number, DEFAULT_ORDER);
    }

    /**
     * 将{@link Number}转换为
     *
     * @param number    数字
     * @param byteOrder 端序
     * @return bytes
     */
    public static byte[] numberToBytes(Number number, ByteOrder byteOrder)
    {
        if (number instanceof Byte) {
            return new byte[]{number.byteValue()};
        } else if (number instanceof Double) {
            return doubleToBytes((Double) number, byteOrder);
        } else if (number instanceof Long) {
            return longToBytes((Long) number, byteOrder);
        } else if (number instanceof Integer) {
            return intToBytes((Integer) number, byteOrder);
        } else if (number instanceof Short) {
            return shortToBytes((Short) number, byteOrder);
        } else if (number instanceof Float) {
            return floatToBytes((Float) number, byteOrder);
        } else {
            return doubleToBytes(number.doubleValue(), byteOrder);
        }
    }

    /**
     * byte[]转换为指定类型数字
     *
     * @param <T>         数字类型
     * @param bytes       byte数组
     * @param targetClass 目标数字类型
     * @param byteOrder   端序
     * @return 转换后的数字
     * @throws IllegalArgumentException 不支持的数字类型，如用户自定义数字类型
     */
    @SuppressWarnings("unchecked")
    public static <T extends Number> T bytesToNumber(byte[] bytes, Class<T> targetClass, ByteOrder byteOrder) throws IllegalArgumentException
    {
        Number number;
        if (Byte.class == targetClass) {
            number = bytes[0];
        } else if (Short.class == targetClass) {
            number = bytesToShort(bytes, byteOrder);
        } else if (Integer.class == targetClass) {
            number = bytesToInt(bytes, byteOrder);
        } else if (AtomicInteger.class == targetClass) {
            number = new AtomicInteger(bytesToInt(bytes, byteOrder));
        } else if (Long.class == targetClass) {
            number = bytesToLong(bytes, byteOrder);
        } else if (AtomicLong.class == targetClass) {
            number = new AtomicLong(bytesToLong(bytes, byteOrder));
        } else if (LongAdder.class == targetClass) {
            final LongAdder longValue = new LongAdder();
            longValue.add(bytesToLong(bytes, byteOrder));
            number = longValue;
        } else if (Float.class == targetClass) {
            number = bytesToFloat(bytes, byteOrder);
        } else if (Double.class == targetClass) {
            number = bytesToDouble(bytes, byteOrder);
        } else if (DoubleAdder.class == targetClass) {
            final DoubleAdder doubleAdder = new DoubleAdder();
            doubleAdder.add(bytesToDouble(bytes, byteOrder));
            number = doubleAdder;
        }
//        else if (BigDecimal.class == targetClass) {
//            number = NumberUtil.toBigDecimal(bytesToDouble(bytes, byteOrder));
//        }
        else if (BigInteger.class == targetClass) {
            number = BigInteger.valueOf(bytesToLong(bytes, byteOrder));
        } else if (Number.class == targetClass) {
            // 用户没有明确类型具体类型，默认Double
            number = bytesToDouble(bytes, byteOrder);
        } else {
            // 用户自定义类型不支持
            throw new IllegalArgumentException("Unsupported Number type: " + targetClass.getName());
        }

        return (T) number;
    }
}
